package com.mingshashan.building.easy.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mingshashan.building.easy.core.dao.IDictionaryMapper;
import com.mingshashan.building.easy.core.entity.Dictionary;
import com.mingshashan.building.easy.core.exception.EasyErrorCoded;
import com.mingshashan.building.easy.core.service.IDictionarySerivce;
import com.mingshashan.building.easy.core.vo.DictionaryCreationVO;
import com.mingshashan.building.easy.core.vo.DictionaryTree;
import com.mingshashan.building.easy.core.vo.DictionaryVO;
import com.mingshashan.building.easy.id.generator.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

/**
 * DictionarySerivceImpl
 *
 * @author jasonxu
 */
@Service
public class DictionaryServiceImpl implements IDictionarySerivce {

    @Autowired
    private IDictionaryMapper dictionaryMapper;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private IdGenerator idGenerator;

    @Override
    public DictionaryVO add(DictionaryCreationVO dictionaryCreationVO) {
        Assert.notNull(dictionaryCreationVO, "dictionaryCreationVO can not be null");
        if (!StringUtils.isBlank(dictionaryCreationVO.getParentCode())) {

            if (dictionaryCreationVO.getCode().equals(dictionaryCreationVO.getParentCode())) {
                throw EasyErrorCoded.DICT_CODE_NOT_EQUAL_TO_PARENT_CODE.exception();
            }
            dictionaryCreationVO.setParentCode(StringUtils.trim(dictionaryCreationVO.getParentCode()));
            checkParentDictCodeNotExist(dictionaryCreationVO.getParentCode());
        }

        Dictionary dictionary = modelMapper.map(dictionaryCreationVO, Dictionary.class);

        checkDictCodeExist(dictionaryCreationVO.getCode());

        dictionary.setId(idGenerator.nextId());
        int insert = dictionaryMapper.insert(dictionary);
        return modelMapper.map(dictionary, DictionaryVO.class);
    }

    @Override
    public DictionaryVO getById(Long id) {
        Dictionary dictionary = dictionaryMapper.selectById(id);

        if (ObjectUtils.isEmpty(dictionary)) {
            throw EasyErrorCoded.DICT_NOT_EXIST_BY_ID.exception(HttpStatus.BAD_REQUEST, id);
        }

        return modelMapper.map(dictionary, DictionaryVO.class);
    }

    @Override
    public DictionaryVO getByCode(String code) {
        Dictionary dictionary = selectByCode(code);

        if (ObjectUtils.isEmpty(dictionary)) {
            throw EasyErrorCoded.DICT_NOT_EXIST_BY_CODE.exception(HttpStatus.BAD_REQUEST, code);
        }

        return modelMapper.map(dictionary, DictionaryVO.class);
    }

    @Override
    public DictionaryVO update(Long id, DictionaryVO dictionaryVO) {
        Dictionary dictionary = dictionaryMapper.selectById(id);

        if (ObjectUtils.isEmpty(dictionary)) {
            throw EasyErrorCoded.DICT_NOT_EXIST_BY_ID.exception(HttpStatus.BAD_REQUEST, id);
        }

        modelMapper.map(dictionaryVO, dictionary);
        dictionaryMapper.updateById(dictionary);
        return modelMapper.map(dictionary, DictionaryVO.class);
    }

    @Override
    public DictionaryTree getRootDictionaryTree(String rootCode) {


        return null;
    }

    @Override
    public void delete(Long id) {
        dictionaryMapper.deleteById(id);
    }

    /**
     * check parent dict doce
     *
     * @param code
     */
    private void checkParentDictCodeNotExist(String code) {
        Dictionary dictionary = selectByCode(code);

        if (ObjectUtils.isEmpty(dictionary)) {
            throw EasyErrorCoded.DICT_PARENT_NOT_EXIST_BY_CODE.exception(HttpStatus.BAD_REQUEST, code);
        }
    }

    /**
     * check dict code
     *
     * @param code
     */
    private void checkDictCodeExist(String code) {
        Dictionary dictionary = selectByCode(code);

        if (!ObjectUtils.isEmpty(dictionary)) {
            throw EasyErrorCoded.DICT_ALREADY_EXIST_BY_CODE.exception(HttpStatus.BAD_REQUEST, code);
        }
    }

    /**
     * select dictionary by code
     *
     * @param code
     * @return
     */
    private Dictionary selectByCode(String code) {
        QueryWrapper<Dictionary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", code);
        return dictionaryMapper.selectOne(queryWrapper);
    }
}
